package com.vteba.security.filter;

import java.util.Collection;
import java.util.Map;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;

/**
 * 默认的Spring Security的认证令牌。
 * @see DefaultUserAuthenticationFilter
 * @author yinlei
 * @date 2014年11月4日 上午10:40:09
 */
public class DefaultUserAuthenticationToken extends AbstractAuthenticationToken {

	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

	// ~ Instance fields
	// ================================================================================================

	private Object principal; // 身份
	private Object credentials; // 令牌
	private String orgCode;
	private String authCode;
	private Map<String, Object> params;

	// ~ Constructors
	// ===================================================================================================

	public DefaultUserAuthenticationToken(Object principal, Object credentials, String orgCode, String authCode) {
		//super(principal, credentials);
		super(null);
		this.principal = principal;
		this.credentials = credentials;
		this.orgCode = orgCode;
		this.authCode = authCode;
	}
	
	public DefaultUserAuthenticationToken(Collection<? extends GrantedAuthority> authorities,
			Object principal, Object credentials, String orgCode, String authCode) {
		//super(principal, credentials, authorities);
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		this.orgCode = orgCode;
		this.authCode = authCode;
		setAuthenticated(true);
	}

	/**
	 * This constructor can be safely used by any code that wishes to create a
	 * <code>UsernamePasswordAuthenticationToken</code>, as the
	 * {@link #isAuthenticated()} will return <code>false</code>.
	 *
	 */
	public DefaultUserAuthenticationToken(Object principal, Object credentials) {
		super(null);
		this.principal = principal;
		this.credentials = credentials;
		setAuthenticated(false);
	}

	/**
	 * This constructor should only be used by
	 * <code>AuthenticationManager</code> or <code>AuthenticationProvider</code>
	 * implementations that are satisfied with producing a trusted (i.e.
	 * {@link #isAuthenticated()} = <code>true</code>) authentication token.
	 *
	 * @param principal
	 * @param credentials
	 * @param authorities
	 */
	public DefaultUserAuthenticationToken(Object principal, Object credentials,
			Collection<? extends GrantedAuthority> authorities) {
		//super(principal, credentials, authorities);
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		super.setAuthenticated(true); // must use super, as we override
	}

	// ~ Methods
	// ========================================================================================================

	public Object getCredentials() {
		return this.credentials;
	}

	public Object getPrincipal() {
		return this.principal;
	}

	public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
//		if (isAuthenticated) {
//			throw new IllegalArgumentException(
//					"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
//		}
		super.setAuthenticated(true);
	}

	@Override
	public void eraseCredentials() {
		super.eraseCredentials();
		credentials = null;
	}

	public String getOrgCode() {
		return orgCode;
	}

	public void setOrgCode(String orgCode) {
		this.orgCode = orgCode;
	}

	public String getAuthCode() {
		return authCode;
	}

	public void setAuthCode(String authCode) {
		this.authCode = authCode;
	}

	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}
}
